Properties for implementing vendor blocks

This article contains statements that can be used when creating vendor blocks – in particular, the statements to create the interface of the vendor block. Moreover, there are some examples illustrating some of the possibilities for the interface.

Information on vendor block

The interface for a vendor block (= vendor →function block or vendor →function) is created in an ST-object whereas the implementation for a vendor block is created in →C.
Usually, a vendor block will be integrated in a custom library. But it is also possible to solely use a vendor block within the project in which the vendor block has been created.

(warning) Restrictions: The following variables are not supported in the interface of vendor blocks:

  • →temporary variables (VAR_TEMP...END)
    If you need temporary variables without storing behavior, create them within the implementation functionality.

  • →external variables (VAR_EXTERNAL...END)

    Moreover, →methods are not supported for implementing a vendor block.

Please observe:

  • This article contains reference documentation of the statements that are designated to create the interface of vendor blocks. Of course, you will need to use other statements as well – for instance, the sections VAR_INPUT ... END_VARVAR_OUTPUT ... END_VARVAR_IN_OUT ... END_VAR. See "Supported ST-syntax" for information on these possibilities (or other statements that are not listed here).

  • The following files are needed for the implementation:

    File

    Contents

    the H-file

    the data type for the vendor block, initialization macros (INIT, WINIT) and – if no C-file is used – the implementation (usually by means of a macro)
    See "The structure of the needed H-file", if you are interested in the basic structure of an H-file.

    an optional C-file

    the implementation (if the implementation is not realized within the H-file)
    All C-files are appended when the application is built so that one C-file is used for compiling. Therefore, the single C-files might have an impact on other C-files as well. Neuron recommends resetting a define at the end of the C-file, if the define is valid for one C-file only.

    The fact, whether a C-file will be used, is controlled by the definition functionHasCFile within the statement { ImplementationProperties ( ) }. See below for more information.

    optional O-files and/or lib-files

    The fact, whether files for additional objects and/or libraries will be used, is controlled by the definitions additionalObjects and additionalLibraries within the statement { ImplementationProperties ( ) }. See below for more information.

    The creation of the contents of the H-file and the C-file is beyond the scope of this article. See the article "Details: Creating a vendor block" for an instruction on how to have the implementation stubs in the C-/H-file created.

  • The statements {...} are also known as →pragmas according to the IEC-standard. The following statements may contain integer literals or →character string literals in pragmas.  A character string literal in pragmas may be enclosed in the double quote character " as well as in the single quote character '. For the sake of convenience, this article uses the double quote character " for most of the character string literal in pragmas. 

In this article:

Basic statements

You need to insert one of the following statements as the first line of the ST-object that contains the interface of the required vendor block.

Statement

Purpose

{CustomImplementation}

This statement identifies the block as vendor block to be used for a library.
(info) Due to this statement, vendor blocks in C-code are also called CustomImpl blocks in the everyday language of Neuron.

This statement has the following effects:

  • Neuron Power Engineer does not create a C- and H-file within the sub-folder src-gen (as Neuron Power Engineer would automatically do). Instead Neuron Power Engineer requires the appropriate files within the sub-folder src-code (parallel to the ST-object with the interface). See the article "Details: Creating a vendor block" for an instruction.

  • If you are specifying the vendor block within a library configuration, the H- and C-file will automatically be integrated within the library by default. When the library with the vendor block is deployed, it will not be possible to create a library variant for the vendor block.

(info) If you want to use a C-file, specify the definition functionHasCFile within the statement { ImplementationProperties ( ) } as well. See below for more information.

{CustomImplementation, CustomNameSpace := Name}

CustomNameSpace := Name is an optional part that you can use to better identify the code for the block.

Observe: Neuron recommends using the NAMESPACE ... END_NAMESPACE statements for the vendor block interface in order to avoid possible conflicts with other blocks. See "Namespaces in ST" for details on these statements.
If you do not want to use the NAMESPACE ... END_NAMESPACE statements, you might want to add the part CustomNameSpace := Name. This does not avoid conflicts with other blocks. However, the name specified for CustomNameSpace is included in the file names for the H-/C–file and in the H-/C-code itself. Subsequently, you are able to better identify the code for the block.

(info) The name specified for the optional definition implementationName within the statement { ImplementationProperties ( ) } (see below for more information) is also included in the file names for the H-/C–file.

Interface statements

Specify the interface statements to determine the block interface (e.g. background color, height/width).

Do not save any changes done within the interface editor.

Usually, you would use the interface editor to create the block interface. But when creating vendor blocks, use the interface editor only to check the interface.
If you save any changes done within the interface editor, it might be possible that already existing statements required for the vendor block are deleted/destroyed. At present, the interface editor is not able to correctly display/handle all statements for vendor blocks.

 

Syntax
{CustomImplementation}
NAMESPACE com.oem1.lib1
  FUNCTION_BLOCK name | FUNCTION name : data-type
    USING Namespace_1; (* possible statement, if a namespace should be used *)
 
    { IO-name_1 { IO_definition_1, IO_definition_2, IO_definition_3 };
      IO-name_2 { IO_definition_1, IO_definition_2, IO_definition_3 };
      ...
      Interface_definition_1;
      Interface_definition_2;
      ...
    };
 
    { ImplementationProperties (...) };
    VAR | VAR_INPUT | VAR_OUTPUT | VAR_IN_OUT | VAR_GLOBAL | VAR_EXTERNAL
      ...
    END_VAR
  END_FUNCTION_BLOCK | END_FUNCTION
END_NAMESPACE

The definitions for IOs { IO_definition_1, IO_definition_2, IO_definition_3 } are applied to the specified variable of the vendor block, e.g.  IO-name_1Neuron Power Engineer supports the definitions for IOs for

The general term will be "variable" in the following description.

IO definition

Purpose

loc := "orientation"

determines the orientation of the specified variable
Possible value for orientation: left, right, top or bottom
If this IO definition is missing, the default value is used: left for inputs, right for outputs
Please note:

  • In case of an in-out variable, it is  possible to change the position only but not the orientation. Reason: It is only allowed to position the input connection point of an in-out variable on the left block edge, the output connection point is automatically positioned on the opposite position on the right block edge.

  • It is not possible to change the position or orientation of the return value for a function within the interface editor.

index := #

determines the position of the specified variable
Possible value for #: an integer value, starting with 0
If this IO definition is missing, the next free position will be used for the position.

(warning) If the variable is located outside of height and width and without the definition expandableGUI, a call of the block inserted into the FBD-editor will automatically be enlarged so that the call contains all variables.

altName := "name"

determines the alternative name of the specified variable

The interface definitions, e.g.  Interface_definition_1, are applied to the vendor block.

Interface definition

Purpose

height := #

determines the height of the block when the block is inserted into the FBD-editor
Possible value for #: an integer value – If no height is specified, the height of the block is automatically calculated.

smartWidth := #

determines the width of the block when the block is inserted into the FBD-editor
Possible value for #: an integer value – If no width is specified by width is used to determine the width of the block.
Neuron recommends to use smartWidth for smart styling and width for legacy styling.

width := #

like smartWidth: determines the width of the block when the block is inserted into the FBD-editor
Possible value for #: an integer value – If no width is specified, the width of the block is automatically calculated.

minHeight := #

determines the minimum height of the block – After the block has been inserted into the FBD-Editor, the block can be made smaller up to the specified minimum height.
Possible value for #: an integer value

maxHeight := #

determines the maximum height of the block – After the block has been inserted into the FBD-Editor, the block can be enlarged up to the specified maximum height.
Possible value for #: an integer value

minWidth := #

determines the minimum width of the block – After the block has been inserted into the FBD-Editor, the block can be made smaller up to the specified minimum width.
Possible value for #: an integer value

maxWidth := #

determines the maximum width of the block – After the block has been inserted into the FBD-Editor, the block can be enlarged up to the specified maximum width.
Possible value for #: an integer value

minInputs := #

determines the number of inputs that are required for the correct functionality of the vendor block
Possible value for #: an integer value

There will be a warning, if a call of the block is inserted into an editor and too few inputs of the block call are connected within the FBD-editor or if too few parameters are specified for the block call within the ST-editor. In order to avoid the warning, you must connect or specify the required number of inputs or at least the input which is the last of them.
In case of minInputs := 3, you would have to connect the first 3 inputs or at least the 3rd input in order to avoid the warning. The connection of the 3rd input is sufficient because Neuron Power Engineer assigns the default initial value to the inputs that are not connected.

(warning) If you are specifying this definition, the best practice is to add the definition expandableGUI.  The definition expandable within the statement { ImplementationProperties ( ) } might be needed as well (see below for more information).

fixedSize

makes the block to be of a fixed size
If a call of the block is inserted into an FBD-editor, the call will be inserted with a fixed size (= the specified height and the width). It will not be possible to make the block smaller or larger.

Subsequently, the specifications for minHeight, maxHeight, minWidth and maxWidth are ignored. Instead the specifications for height and width are applied only.

hideIONames

hides the names of the inputs, outputs, in-outs and the return value of a function

hideOutputOfVarInOut

applied for in-out variables (= VAR_IN_OUT) so that the following is valid:

Neuron Power Engineer displays the user interface of the block as it is in logi.CAD/32. This means that only the input connection point of the in-out variable is displayed in Neuron Power Engineer. It is also possible that other variables are located on the opposite position of the input connection point.
See the system blocks MOVE_2D_ARRAY and SEL_2D_ARRAY (provided in the system library Standard) for the usage of this setting.

(info) This setting is automatically applied when a block with in-out variables is migrated from logi.CAD/32  to Neuron Power Engineer. The interface editor does not provide a matching GUI element for this interface statement.

altName := "name"

determines the alternative name for the block
For smart styling, the alternative name will be applied when its value is not empty.

vNameAlignment := "value"

determines the vertical alignment of the block name (or of the alternative name for the block)
Possible value for value:

  • top: The name is displayed at the top of the interface, but above the first possible input, output, in-out or EN/ENO.

  • baseline: The name is displayed at the top of the interface, but on the same vertical position as the first possible input, output, in-out or EN/ENO (= on the baseline).

  • center: The name is displayed in the center of the interface.

  • bottom: The name is displayed at the bottom of the interface.

See the following examples for alignment.
If this definition is missing, the default value center is used.

bgColor := "value"

determines the background color of the block
Possible value for value: a color name according to https://www.w3schools.com/cssref/css_colors.asp

Neuron recommends that you and/or your system integrator do not use yellow shades when designing FBD-elements because the color "Yellow" is used for tracking safe signals when developing safety-related applications. This recommendation applies in particular when you are using the legacy styling. Neuron Power Engineer does not check if colors are already used elsewhere. So the use of the yellow shades by you and/or your system integrator could have the consequence that "yellow" might also identify a non-safe logic as well.

fgColor := "value"

determines the color of the block text; Possible values: see the background color of the block

iofgColor := "value"

determines the color of the inputs, outputs, in-outs and the return value of a function; Possible values: see the background color of the block

safeStyle similar to bgColor but without a value because the background color of the block is automatically determined to be "gold"
Neuron recommends to use the property safeStyle only if a block tracks safe signals when developing safety-related applications and the block should be displayed with this gold background color in the smart styling. Do not misuse the property safeStyle for other blocks because the color "Yellow" is used for tracking safe signals when developing safety-related applications. The misuse of the property safeStyle could have the consequence that the color "Gold" might also identify a non-safe logic as well.

expandableGUI

determines that the vendor block is an extensible block, which means it can be expanded by additional inputs/outputs (when the block is made larger)
Those additional inputs/outputs must be located in a position between the minimum height/width and the maximum height/width of the block. An inserted call will not automatically be enlarged so that all variables are displayed.

pageSize := "valuexvalue"

determines the page size when the FBD-logic is displayed within the graphical FBD-editor
(warning) This interface definition is not relevant for the interface of vendor blocks.

instanceName := {definitions};

determines the layout of the instance name for a function block instance
Example: instanceName := {visible, position := "manual", x := 0, y := 20, width := 300, height := 20, bgColor := "beige", fgColor := "black", border};
Possible definitions are:

  • visible: makes the instance name to be displayed; Without this definition, the instance name is not displayed.
    (info) The statement instanceNameVisible was used in Neuron Power Engineer versions < 2.9.0 and is no longer supported.

  • position: determines whether the displayed instance name is displayed above the top block edge or within the interface; Possible values: top or manual

  • x and y: determines where within the interface the instance name is displayed (only evaluated in case of position := "manual";); Possible values are integer values. Without these definitions, the instance name will be displayed starting at the left upper corner.

  • width and height: determines the width and height for the displayed instance name (only evaluated in case of position := "manual";); Possible values are integer values. Without these definitions, the default size is used.
    If there is no sufficient space to display the complete instance name, the instance name will be truncated.

  • bgColor:  determines the background color for the displayed instance name; Possible values: see the background color of the block

  • fgColor:  determines the text color for the displayed instance name; Possible values: see the background color of the block

  • border: makes the instance name be displayed with a border; Without this definition, no border is displayed.

  • alignment: determines the alignment of the instance name; Without this definition, the instance name is aligned as if the value centered is specified.
    Possible value for alignmenttop-lefttop-centertop-rightcenter-leftcentercenter-rightbottom-leftbottom-center or bottom-right

valueFields := {definitions};

add value fields for inputs within the interface and determines the layout of them
Example for 2 value fields: valueFields := {{x := 60, y := 0, width := 160, height := 19, variable := "in1", initValue := "5"}, {x := 90, y := 20, width := 80, height := 39, variable := "in2", initValue := "10", fgColor := "black", border}};
Possible definitions are:

  • x and y: determines where the value field is displayed; Possible values are integer values.

  • width and height: determines the width and height of the value field; Possible values are integer values.

  • variable:  determines for which input the value field is valid; Possible values are the names of existing inputs.

  • initValue: determines the content of the value field; Possible values are literals according to the data type of the relevant input.

  • fgColor:  like the same definition for the instance name

  • border: like the same definition for the instance name

  • alignment: like the same definition for the instance name; Without this definition, the text within the value field is aligned as if the value centered-left is specified.

commentFields := {definitions};

add comment fields within the interface and determines the layout of them
Example for 2 comment fields: commentFields := {{x := 40, y := 110, width := 200, height := 19, text := "comment 1", fgColor := "black", bgColor := "beige", border}, {x := 110, y := 150, width := 190, height := 19, text := "comment 2"}};Possible definitions are:

  • x and y: determines where the comment field is displayed; Possible values are integer values.

  • width and height: determines the width and height of the comment field; Possible values are integer values.

  • text: determines the content of the comment field

  • fgColor:  like the same definition for the instance name

  • bgColor:  like the same definition for the instance name

  • border: like the same definition for the instance name

  • alignment: like the same definition for the instance name; Without this definition, the text within the comment field is aligned as if the value centered-left is specified.

Examples with interface statements

The interface of the following example...

will look like this:

Example
{CustomImplementation}
NAMESPACE com.oem1.lib1
FUNCTION_BLOCK myFB_01
  {
    IN1 {altName := "I1"};
    IN2 {index := 2, altName := "I2"};
    IN3 {index := 3, altName := "I3"};
    IN4 {index := 4, altName := "I4"};
    OUT {index := 1, altName := "O"};
    minInputs := 2;
    altName := "TST";
    vNameAlignment := "center";
    height := 58;
    width := 100;
    minWidth := 70;
    maxWidth := 150;
    bgColor := "DodgerBlue";
    expandableGUI;
  }
 
  VAR_INPUT
    IN1 : BOOL;
    IN2 : BOOL;
    IN3 : BOOL;
    IN4 : BOOL;
  END_VAR
  VAR_OUTPUT
    OUT : BOOL;
  END_VAR
END_FUNCTION_BLOCK
END_NAMESPACE

Please note the warning icons due to minInputs := 2;
The icon will disappear when you connect the first 2 inputs or at least the 2nd input.

Example for alignment "top"
{CustomImplementation}
NAMESPACE com.oem1.lib1
FUNCTION_BLOCK myFB_T
  {
    altName := "TOP";
    vNameAlignment := "top";
    bgColor := "DarkBlue";
    instanceName := {visible};
  }
  VAR_IN_OUT
    IO1 : BOOL;
    IO2 : BOOL;
    IO3 : BOOL;
  END_VAR
END_FUNCTION_BLOCK
END_NAMESPACE
Example for alignment "baseline"
{CustomImplementation}
NAMESPACE com.oem1.lib1
FUNCTION_BLOCK myFB_BL
  {
    altName := "BASELINE";
    vNameAlignment := "baseline";
    bgColor := "DarkBlue";
    instanceName := {visible};
  }
  VAR_IN_OUT
    IO1 : BOOL;
    IO2 : BOOL;
    IO3 : BOOL;
  END_VAR
END_FUNCTION_BLOCK
END_NAMESPACE

Example for alignment "center"

{CustomImplementation}
NAMESPACE com.oem1.lib1
FUNCTION_BLOCK myFB_C
  {
    altName := "CENTER";
    vNameAlignment := "center";
    bgColor := "DarkBlue";
    instanceName := {visible};
  }
  VAR_IN_OUT
    IO1 : BOOL;
    IO2 : BOOL;
    IO3 : BOOL;
  END_VAR
END_FUNCTION_BLOCK
END_NAMESPACE
Example for alignment "bottom"
{CustomImplementation}
NAMESPACE com.oem1.lib1
FUNCTION_BLOCK myFB_B
  {
    altName := "BOTTOM";
    vNameAlignment := "bottom";
    bgColor := "DarkBlue";
    instanceName := {visible};
  }
  VAR_IN_OUT
    IO1 : BOOL;
    IO2 : BOOL;
    IO3 : BOOL;
  END_VAR
END_FUNCTION_BLOCK
END_NAMESPACE

Please note the warning icons due to declared in-outs.
The icon will disappear when the input connection points are connected.

Statement 'ImplementationProperties' and its definition

The statement { ImplementationProperties ( ) } is a container for definitions to control the code generation for the vendor blocks – within the application in which the vendor block is created as well as within a library in which the vendor block will be integrated.

Syntax
{CustomImplementation}
NAMESPACE com.oem1.lib1
  FUNCTION_BLOCK name | FUNCTION name : data-type
    USING Namespace_1; (* possible statement, if a namespace should be used *)
    { list of interface statements; }
 
    { ImplementationProperties (definition_1; definition_2; ...) };
 
    VAR | VAR_INPUT | VAR_OUTPUT | VAR_IN_OUT | VAR_GLOBAL | VAR_EXTERNAL
      ...
    END_VAR
  END_FUNCTION_BLOCK | END_FUNCTION
END_NAMESPACE

Definition

Purpose

Definitions that are affecting the structure of files

additionalLibraries and additionalObjects

determines additional objects and/or additional libraries to be integrated when the application is built for the target system

(info) Observe: When the library with the vendor block is generated, you are able to specify the following statements within the library configuration (see "Example for library configuration" below):

  • SUPPORTED_PTKS specifying the platform – This statement must be specified.

  • COMMON_SOURCE specifying the location of the additional objects/libraries – This statement is optional.

See the example below for more information.

extraIncludes

determines one or more additional required H-files
Observe that you have to enhance the implementation in the basic H-file yourself so that the implementation of the additional H-files is used.

By default, the additional files must be located in the sub-folder src-code of the project. If you want to change the location of the files, specify the statement COMMON_SOURCE := sub-folder of project; within the library configuration (see "Example for library configuration" below). In case of COMMON_SOURCE := MoreFiles; Neuron Power Engineer searches within path project/MoreFiles/src-code for the additional files.

functionHasCFile

determines to use a C-file as well (besides the H-file)

implementationName

determines a different POU name as part of file name for the H-file as well as for the C-file (if the definition functionHasCFile is specified as well)
This definition is useful in particular, if several identical functions are to be implemented within the same file.

Definitions that are affecting the content of the H-file (type def structure, implementation)

expandable

(warning) This definition is necessary for the correct code generation of an extensible block (see the interface definition expandableGUI)
Observe that for each input, you have to create one C-function within the implementation. The name __x must be added to the function name for each input but replace x by the input number (see example below). The best practice is to start the C-functions with the input number specified by minInputs.

It is sufficient for vendor blocks to only include the definition expandable (see the following examples). A better practice is to include the definition expandable as well as the interface definition expandableGUI.

passConcreteTypeParameter

determines to add the TYPE argument as 1st argument in the implementation within the H-file
This definition is needed in particular, if the block is a mapped block (i.e. if the definitions untypedCFunctionNameBlacklist and/or untypedCFunctionNameWhitelist are used in the interface as well).

untypedCFunctionNameWhitelist and untypedCFunctionNameBlacklist

maps the vendor block – Consequence: A list of concrete data types is created based on the specified values. For each one of these concrete data types, __ANY must be used instead of the concrete data type within the implementation (e.g. in the H-file). See "The structure of the needed H-file" and/or the following examples, if you are unsure which part of the H-file is the implementation.
For all other data types (and without these definitions), the name of the concrete data type (e.g. __BOOL) must be used within the implementation.

untypedCFunctionNameWhitelist specifies the data types for which the definition should be applied, untypedCFunctionNameBlacklist specifies the data types for which the definition should not be applied. It is allowed to use untypedCFunctionNameWhitelist without untypedCFunctionNameBlacklist but it is not allowed to just use untypedCFunctionNameBlacklist.
These definitions are only useful, if inputs of the vendor block are declared based on a generic data type (e.g. ANY_MAGNITUDE or ANY_BIT).

Allowed values for both definitions (as a comma-separated list):

  • all →generic data types and all elementary data types

  • short form instead of specific elementary data types
    T (instead of TIME), LT (instead of LTIME), DT (instead of DATE_AND_TIME), LDT (instead of LDATE_AND_TIME), D (instead of DATE), LD (instead of LDATE), TOD (instead of TIME_OF_DAY), LTOD (instead of LTOD)

  • values for more complex data types
    (warning) Please contact Neuron on the required content of the H-file, if your vendor block is to support more complex data types (such as structures, arrays, references) or the elementary data types CHAR or STRING.

    • REF_TO generic data type, e.g. REF_TO ANY_BIT
      Such a value is applied for references to the appropriate elementary data types for the specified generic data type.

    • REF_TO elementary data type, e.g. REF_TO INT
      Such as value is applied for references to the specified elementary data types.

    • ARRAY
      This value is applied for all arrays with one dimension only. (error) Arrays with more dimensions are not supported for vendor blocks.

    • REF_TO ARRAY
      This value is applied for references to arrays with one dimension only.

    • ARRAY_OF_STRUCT
      This value is applied for all arrays of structures as well as for references to arrays of structures.

useUntypedTypeStructure

determines that the concrete data type must not be added for the name of the typedef structure – instead the generic name of the block must be used
This definition is useful in particular, if inputs of a vendor function are declared based on a generic data type (e.g. ANY_NUM) but the return value is declared based on a concrete data type (e.g. TIME).

Definitions that are affecting the validation when the vendor block is called

allowedTypeWhitelist and allowedTypeBlacklist

determines which data types are supported when the inputs/outputs of the vendor block call are connected
If you connect an element with an allowed data type, there will be no error message. But if you connect an element with an illegal data type, the code or the logic will be highlighted as faulty.

allowedTypeWhitelist specifies the allowed data types, allowedTypeBlacklist specifies the illegal data types. It is allowed to use both definitions or just one of the definitions. Without the definition allowedTypeWhitelist, all data types are allowed (default is ANY). Without the definition allowedTypeBlacklist, no data type is illegal.
These definitions are only useful, if inputs of the vendor block are declared based on a generic data type (e.g. ANY_MAGNITUDE or ANY_BIT).

Allowed values for both definitions (as a comma-separated list):

  • all generic data types and all elementary data types
    See: What is a generic data type? What are the appropriate elementary data types?

  • short form instead of specific elementary data types
    T (instead of TIME), LT (instead of LTIME), DT (instead of DATE_AND_TIME), LDT (instead of LDATE_AND_TIME), D (instead of DATE), LD (instead of LDATE), TOD (instead of TIME_OF_DAY), LTOD (instead of LTOD)

(warning) Please contact Neuron, if your vendor block is to support the elementary data types CHAR or STRING.

returnValueMustBeAssigned

determines that – in the case of a function call – the return value must be assigned to a concrete variableThis definition is useful for functions only.

What is a generic data type? What are the appropriate elementary data types? See →generic data types

Examples with implementation properties

(info) The following examples are mostly using the system blocks of Neuron Power Engineer to illustrate the usage of the above definitions. Observe that because of internal reasons, the system blocks are using the part CustomNameSpace := Name instead of the rather recommended statement NAMESPACE ... END_NAMESPACE statements.

If you are interested in how Neuron has implemented the system blocks and you want to check out the appropriate H- and C-files in detail: Contact Neuron for the sources containing the appropriate system library.
Usually, the sources are a Neuron Power Engineer project containing the system blocks and a library configuration.

Examples affecting the structure of files

Example with 'additionalLibraries' and  'additionalObjects'

Example 1 for interface
{ CustomImplementation}
NAMESPACE Copies
FUNCTION_BLOCK myFB01 
  { ImplementationProperties (additionalLibraries:="additionalLibrary1,additionalLibrary2"; additionalObjects:="additionalObject1, additionalObject2"; )}
  VAR_INPUT
  ...
END_FUNCTION_BLOCK
END_NAMESPACE

The generation of the library MyLibWithVendorBlocks (see the next example) requires the additional library files additionalLibrary1 and additionalLibrary2 as well as the additional object files additionalObject and additionalObject2
Please observe:

  • The location of these files depends on the statements COMMON_SOURCE and SUPPORTED_PTKS specified within the library configuration. For the following library configuration, the files are searched within the path project/MoreFiles/src-code/WindowsX86Without the statement COMMON_SOURCE, the files are searched within the path project/src-code/WindowsX86

  • The extension of these files depends on the statement SUPPORTED_PTKS as well. For the following library configuration, the files additionalLibrary1.lib and additionalLibrary2.libadditionalObject.o and additionalObject2.o are searched.

Example for library configuration
LIBRARY MyLibWithVendorBlocks
    Version := 0.0.1;
    SUPPORTED_PTKS := WindowsX86;
    COMMON_SOURCE := MoreFiles; 
    FOLDER "folderName"
        IEC := myFB01;
    END_FOLDER
END_LIBRARY

Special behaviors:

  • If you define the platform BuiltInPlc (instead of WindowsX86) within the library configuration, the file location depends on the operating system where the library is used. For Windows, the sub-folder is WindowsX86 (as already specified above), for Linux the sub-folder is LinuxX86.

  • If you are using the vendor block directly within the project (in which you have created the vendor block),  the additional files are searched starting with the target platform. This means if the platform BuiltInPlc is specified within the resource for the project, the additional files are searched within the path project/src-code/BuiltInPlc.

Example with/without 'extraIncludes'

Example for interface
...
{ CustomImplementation , CustomNamespace := iec61131}
...
FUNCTION GET_TYPE_FROM_VARNAME : UDINT
  { altName := ""; vNameAlignment := "center"; width:=208;}
  { ImplementationProperties ( extraIncludes := "RTSSNS.h,RTSSNSUtil.h"; functionHasCFile; ) }
  VAR_INPUT
  ...
END_FUNCTION

The code generation requires the H-file lcfu_iec61131__GET_TYPE_FROM_VARNAME.h, the C-file lcfu_iec61131__GET_TYPE_FROM_VARNAME.c as well as the additional H-files RTSSNS.hRTSSNSUtil.h.
If the library configuration does not specify otherwise, Neuron Power Engineer searches within the path project/src-code for the additional files.

Example with/without 'functionHasCFile'

Example 1 for interface
...
{ CustomImplementation , CustomNamespace := iec61131}
...
FUNCTION FIND : ANY_INT { FIND { altName := "" }; ... }
  { ImplementationProperties ( functionHasCFile; ) }
  VAR_INPUT
  ...
END_FUNCTION

The code generation requires the H-file lcfu_iec61131__FIND.h as well as the C-file named lcfu_iec61131__FIND.c.

Compare the following copy of the system block that has been slightly modified:

Example 2 for interface
{ CustomImplementation}
NAMESPACE Copies
FUNCTION FIND_Copy : INT { FIND { altName := "" }; }
END_FUNCTION
END_NAMESPACE

The code generation requires only the H-file lcfu___copies.FIND_COPY.h. No C-file is required because of the missing definition functionHasCFile.

Example with/without 'implementationName'

Example for interface
...
{ CustomImplementation , CustomNamespace := iec61131}
...
FUNCTION TO_SINT : SINT { hideIONames; ... }
  { ImplementationProperties ( ...; functionHasCFile; implementationName:="CONVERT"; ) }
  VAR_INPUT
  ...
END_FUNCTION
 
 
...
 
FUNCTION TO_INT : INT { hideIONames; ... }
  { ImplementationProperties ( ...; functionHasCFile; implementationName:="CONVERT"; ) }
  VAR_INPUT
  ...
END_FUNCTION

The code generation requires the H-file lcfu_iec61131__CONVERT.h and the C-file lcfu_iec61131__CONVERT.c – instead of the H-files lcfu_iec61131__TO_SINT.h , lcfu_iec61131__TO_INT.h and the C-files lcfu_iec61131__TO_SINT.clcfu_iec61131__TO_INT.c.

Please observe:

  • If the first ST-object containing the function TO_SINT is saved, Neuron Power Engineer auto-generates the files lcfu_iec61131__CONVERT.h and the C-file lcfu_iec61131__CONVERT.c with the implementation stubs for TO_SINT.

  • If the second ST-object containing the function TO_INT is saved later on, Neuron Power Engineer does not update the files lcfu_iec61131__CONVERT.h and the C-file lcfu_iec61131__CONVERT.c to include the implementation stubs for TO_INT.

If you require different implementation stubs for TO_SINT and TO_INT, best practice is to not use the definition implementationName. Only use the definition implementationName, if the same implementation is required within the same file.

Examples affecting the content of the H-file

Example with/without 'expandable'

Example 1 for interface

...
{ CustomImplementation , CustomNamespace := iec61131}
...
FUNCTION ADD : ANY_MAGNITUDE { minInputs := 2; ... }
  { ImplementationProperties ( expandable; untypedCFunctionNameWhitelist:="ANY_NUM,ANY_DURATION"; ) }
  VAR_INPUT
    IN1 : ANY_MAGNITUDE;
    ...
    IN16 : ANY_MAGNITUDE;
  END_VAR
END_FUNCTION
Code required by the code generation
#define  lcfu_iec61131__ADD__ANY__2(LC_this, IN1, IN2, pEPDB) \
   (LC_this)->LC_VD_ADD = LC_MF_ADD_ANY_2(IN1,IN2)
 
#define  lcfu_iec61131__ADD__ANY__3(LC_this, IN1, IN2, IN3,pEPDB) \
   (LC_this)->LC_VD_ADD = LC_MF_ADD_ANY_3(IN1,IN2,IN3)
 
#define  lcfu_iec61131__ADD__ANY__4(LC_this, IN1, IN2, IN3,IN4,pEPDB) \
   (LC_this)->LC_VD_ADD = LC_MF_ADD_ANY_4(IN1,IN2,IN3,IN4)
 
#define  lcfu_iec61131__ADD__ANY__5(LC_this, IN1, IN2, IN3,IN4,IN5,pEPDB) \
   (LC_this)->LC_VD_ADD = LC_MF_ADD_ANY_5(IN1,IN2,IN3,IN4,IN5)
 
#define  lcfu_iec61131__ADD__ANY__6(LC_this, IN1, IN2, IN3,IN4,IN5,IN6,pEPDB) \
   (LC_this)->LC_VD_ADD = LC_MF_ADD_ANY_6(IN1,IN2,IN3,IN4,IN5,IN6)
 
#define  lcfu_iec61131__ADD__ANY__7(LC_this, IN1, IN2, IN3,IN4,IN5,IN6,IN7,pEPDB) \
   (LC_this)->LC_VD_ADD = LC_MF_ADD_ANY_7(IN1,IN2,IN3,IN4,IN5,IN6,IN7)
 
#define  lcfu_iec61131__ADD__ANY__8(LC_this, IN1, IN2, IN3,IN4,IN5,IN6,IN7,IN8,pEPDB) \
   (LC_this)->LC_VD_ADD = LC_MF_ADD_ANY_8(IN1,IN2,IN3,IN4,IN5,IN6,IN7,IN8)
 
#define  lcfu_iec61131__ADD__ANY__9(LC_this, IN1, IN2, IN3,IN4,IN5,IN6,IN7,IN8,IN9,pEPDB) \
   (LC_this)->LC_VD_ADD = LC_MF_ADD_ANY_9(IN1,IN2,IN3,IN4,IN5,IN6,IN7,IN8,IN9)
 
#define  lcfu_iec61131__ADD__ANY__10(LC_this, IN1, IN2, IN3,IN4,IN5,IN6,IN7,IN8,IN9,IN10,pEPDB) \
   (LC_this)->LC_VD_ADD = LC_MF_ADD_ANY_10(IN1,IN2,IN3,IN4,IN5,IN6,IN7,IN8,IN9,IN10)
 
#define  lcfu_iec61131__ADD__ANY__11(LC_this, IN1, IN2, IN3,IN4,IN5,IN6,IN7,IN8,IN9,IN10,IN11,pEPDB) \
   (LC_this)->LC_VD_ADD = LC_MF_ADD_ANY_11(IN1,IN2,IN3,IN4,IN5,IN6,IN7,IN8,IN9,IN10,IN11)
 
#define  lcfu_iec61131__ADD__ANY__12(LC_this, IN1, IN2, IN3,IN4,IN5,IN6,IN7,IN8,IN9,IN10,IN11,IN12,pEPDB) \
   (LC_this)->LC_VD_ADD = LC_MF_ADD_ANY_12(IN1,IN2,IN3,IN4,IN5,IN6,IN7,IN8,IN9,IN10,IN11,IN12)
 
#define  lcfu_iec61131__ADD__ANY__13(LC_this, IN1, IN2, IN3,IN4,IN5,IN6,IN7,IN8,IN9,IN10,IN11,IN12,IN13,pEPDB) \
   (LC_this)->LC_VD_ADD = LC_MF_ADD_ANY_13(IN1,IN2,IN3,IN4,IN5,IN6,IN7,IN8,IN9,IN10,IN11,IN12,IN13)
 
#define  lcfu_iec61131__ADD__ANY__14(LC_this, IN1, IN2, IN3,IN4,IN5,IN6,IN7,IN8,IN9,IN10,IN11,IN12,IN13,IN14,pEPDB) \
   (LC_this)->LC_VD_ADD = LC_MF_ADD_ANY_14(IN1,IN2,IN3,IN4,IN5,IN6,IN7,IN8,IN9,IN10,IN11,IN12,IN13,IN14)
 
#define  lcfu_iec61131__ADD__ANY__15(LC_this, IN1, IN2, IN3,IN4,IN5,IN6,IN7,IN8,IN9,IN10,IN11,IN12,IN13,IN14,IN15,pEPDB) \
   (LC_this)->LC_VD_ADD = LC_MF_ADD_ANY_15(IN1,IN2,IN3,IN4,IN5,IN6,IN7,IN8,IN9,IN10,IN11,IN12,IN13,IN14,IN15)
 
#define  lcfu_iec61131__ADD__ANY__16(LC_this, IN1, IN2, IN3,IN4,IN5,IN6,IN7,IN8,IN9,IN10,IN11,IN12,IN13,IN14,IN15,IN16,pEPDB) \
   (LC_this)->LC_VD_ADD = LC_MF_ADD_ANY_16(IN1,IN2,IN3,IN4,IN5,IN6,IN7,IN8,IN9,IN10,IN11,IN12,IN13,IN14,IN15,IN16)
Example 2 for interface
...
{ CustomImplementation , CustomNamespace := iec61131}
...
FUNCTION_BLOCK RS { vNameAlignment := "center"; ... }
  VAR_INPUT
    S : BOOL;
    R1 : BOOL;
  END_VAR
  ...
END_FUNCTION_BLOCK

Code required by the code generation

#define lcfu_iec61131__RS(LC_this, pEPDB) \
        (LC_this)->LC_VD_Q1 = (!(LC_this)->LC_VD_R1) && ((LC_this)->LC_VD_S || (LC_this)->LC_VD_Q1

Example with/without 'passConcreteTypeParameter'

Example for interface
...
{ CustomImplementation , CustomNamespace := iec61131}
...
FUNCTION PACK : ANY_ELEMENTARY { minInputs := 2; ... }
  { ImplementationProperties ( allowedTypeWhitelist:="ANY_ELEMENTARY"; allowedTypeBlacklist:="ANY_CHARS"; expandable; passConcreteTypeParameter; functionHasCFile; untypedCFunctionNameWhitelist:="ANY_ELEMENTARY"; untypedCFunctionNameBlacklist:="ANY_CHARS,BOOL"; ) }
  VAR_INPUT
    IN0 : BYTE;
    ...
    IN7 : BYTE;
  END_VAR
END_FUNCTION
Code required by the code generation
#define lcfu_iec61131__PACK__ANY__2(TYPE,LC_this, v1,v2,pEPDB)                      lcfu_iec61131__PACK__ANY(sizeof(TYPE),&((LC_this)->LC_VD_PACK),2,v1,v2)
...

Example with 'untypedCFunctionNameWhitelist' and without 'untypedCFunctionNameBlacklist' and with both of them

Example 1 for interface
...
{ CustomImplementation , CustomNamespace := iec61131}
...
FUNCTION SUB : ANY_MAGNITUDE { hideIONames; ... }
  { ImplementationProperties ( untypedCFunctionNameWhitelist:="ANY_NUM,ANY_DURATION"; ) }
  VAR_INPUT
  ...
END_FUNCTION

The following list of concrete data types emerges for SUB:

Concrete data types because of white list

Concrete data types after of black list

REALLREAL, USINTUINTUDINTULINT, SINTINTDINTLINT – due to ANY_NUM

TIME – due to ANY_DURATION (Currently, LTIME is not supported in Neuron Power Engineer.) 

identical because there is no black list

The code generation requires that __ANY (instead of __REAL__LREAL__USINT etc.) is used within the implementation (e.g. in the H-file).

Code required by the code generation

/*            Implementation of helper macros (inlined)           */
#define LC_MF_SUB_ANY(IN1,IN2) ((IN1)-(IN2))
 
#define  lcfu_iec61131__SUB__ANY(LC_this, IN1, IN2, pEPDB) \
    (LC_this)->LC_VD_SUB = LC_MF_SUB_ANY(IN1,IN2)

Compare the following system block that is using the white list and the black list:

Example 2 for interface
...
{ CustomImplementation , CustomNamespace := iec61131}
...
FUNCTION OR : ANY_BIT { minInputs := 2; ... }
  { ImplementationProperties ( expandable; untypedCFunctionNameWhitelist:="ANY_BIT"; untypedCFunctionNameBlacklist:="BOOL"; ) }
  VAR_INPUT
  ...
END_FUNCTION

The following list of concrete data types emerges for OR:

Concrete data types because of white list

Concrete data types after of black list

BOOLBYTEWORDDWORDLWORD – due to ANY_BIT

BYTEWORDDWORDLWORD BOOL is removed

The code generation requires that __ANY (instead of __BYTE__WORD__DWORD and __LWORD) is used within the implementation (e.g. in the H-file) but not for the concrete data type BOOL.

Code required by the code generation (extract)
#define  lcfu_iec61131__OR__BOOL__2(LC_this, IN1, IN2, pEPDB) \
   (LC_this)->LC_VD_OR = LC_MF_OR_BOOL_2(IN1,IN2)
 
#define  lcfu_iec61131__OR__BOOL__3(LC_this, IN1, IN2, IN3,pEPDB) \
   (LC_this)->LC_VD_OR = LC_MF_OR_BOOL_3(IN1,IN2,IN3)
...
 
#define  lcfu_iec61131__OR__ANY__2(LC_this, IN1, IN2, pEPDB) \
   (LC_this)->LC_VD_OR = LC_MF_OR_ANY_2(IN1,IN2)
 
#define  lcfu_iec61131__OR__ANY__3(LC_this, IN1, IN2, IN3,pEPDB) \
   (LC_this)->LC_VD_OR = LC_MF_OR_ANY_3(IN1,IN2,IN3)
...

Example with 'useUntypedTypeStructure'

Example 1 for interface
...
{ CustomImplementation , CustomNamespace := iec61131}
...
FUNCTION MUL_TIME : TIME { hideIONames; ... }
  { ImplementationProperties ( useUntypedTypeStructure; ) }
  VAR_INPUT
    IN1 : TIME;
    IN2 : ANY_NUM;
  END_VAR
END_FUNCTION

Usually, the generic data type ANY_NUM of the 2nd input would require that the concrete data types are added for the name of the typedef structure. This is not necessary because of the implementation itself. So useUntypedTypeStructure is used in the interface. 

Code required by the code generation

typedef struct _LC_TD_Function_MUL_TIME
{
    LC_TD_BOOL LC_VD_ENO;
    LC_TD_TIME LC_VD_MUL_TIME;
} LCCG_StructAttrib LC_TD_Function_MUL_TIME;

Compare the following copy of the system block that has been slightly modified: MUL_TIME_Copy is specified without useUntypedTypeStructure.

Example 2 for interface
{ CustomImplementation}
NAMESPACE Copies
FUNCTION MUL_TIME_Copy : TIME { hideIONames; }
  VAR_INPUT
    IN1 : TIME;
    IN2 : ANY_NUM;
  END_VAR
END_FUNCTION

The code generation requires that the concrete data types are added for the name of the typedef structures. Hence, the names for the structures are:

  • MUL_TIME_REAL

  • MUL_TIME_LREAL

  • MUL_TIME_USINT

  • MUL_TIME_UINT

  • MUL_TIME_UDINT

  • MUL_TIME_ULINT

  • MUL_TIME_SINT

  • MUL_TIME_INT

  • MUL_TIME_DINT

  • MUL_TIME_LINT

Code required by the code generation
typedef struct _LC_TD_Function_MUL_TIME_REAL
{
    LC_TD_BOOL LC_VD_ENO;
    LC_TD_TIME LC_VD_MUL_TIME;
} LCCG_StructAttrib LC_TD_Function_MUL_TIME_REAL;
 
 
typedef struct _LC_TD_Function_MUL_TIME_LREAL
{
    LC_TD_BOOL LC_VD_ENO;
    LC_TD_TIME LC_VD_MUL_TIME;
} LCCG_StructAttrib LC_TD_Function_MUL_TIME_LREAL;
 
 
typedef struct _LC_TD_Function_MUL_TIME_USINT
{
    LC_TD_BOOL LC_VD_ENO;
    LC_TD_TIME LC_VD_MUL_TIME;
} LCCG_StructAttrib LC_TD_Function_MUL_TIME_USINT;
 
 
/* and more blocks according to the data type */

Examples affecting the validation when the vendor block is called

Example with 'allowedTypeWhitelist' and without 'allowedTypeBlacklist' and with both of them

Example 1 for interface
...
{ CustomImplementation , CustomNamespace := iec61131}
...
FUNCTION SHL : ANY_ELEMENTARY { vNameAlignment := "center"; width := 100; bgColor := "dodgerblue"; }
  { ImplementationProperties ( allowedTypeWhitelist:="ANY_BIT,ANY_INT"; ) }
  VAR_INPUT
    IN : ANY_ELEMENTARY;
    N : INT;
    END_VAR
END_FUNCTION

The following list of concrete data types emerges for SHL:

Concrete data types because of white list

Concrete data types after of black list

BOOLBYTEWORDDWORDLWORD – due to ANY_BIT

USINTUINTUDINTULINT, SINT, INT, DINT, LINT – due to ANY_INT

identical because there is no black list

These concrete data types are supported when the input IN of a SHL block call is connected.

Example for calls of this function

PROGRAM Test1
  VAR
    result1 : INT;
    result2 : REAL;
  END_VAR
  result1 := SHL(IN := INT#40, N := 1);     (* allowed *)
  result2 := SHL(IN := REAL#40.0, N := 1);  (* NOT allowed *)
END_PROGRAM

Compare the following system block that is using the white list and the black list:

Example 2 for interface

...
{ CustomImplementation , CustomNamespace := iec61131}
...
FUNCTION LIMIT : ANY_ELEMENTARY { LIMIT { altName := ""}; ... }
  { ImplementationProperties ( allowedTypeWhitelist:="ANY_ELEMENTARY"; allowedTypeBlacklist:="ANY_CHARS"; untypedCFunctionNameWhitelist:="ANY_ELEMENTARY"; untypedCFunctionNameBlacklist:="ANY_CHARS"; ) }
  VAR_INPUT
    MN : ANY_ELEMENTARY;
    IN : ANY_ELEMENTARY;
    MX : ANY_ELEMENTARY;
  END_VAR
END_FUNCTION

The following list of concrete data types emerges for LIMIT:

Concrete data types because of white list – due to ANY_ELEMENTARY

Concrete data types after of black list – due to ANY_CHARS

REALLREAL

USINTUINTUDINTULINT

SINTINTDINTLINT

TIME

BOOL, BYTE, WORD, DWORD, LWORD

STRING

CHAR

DATE_AND_TIME, DATE, TIME_OF_DAY, LDATE

REALLREAL

USINTUINTUDINTULINT

SINTINTDINTLINT

TIME

BOOL, BYTE, WORD, DWORD, LWORD

 

 

DATE_AND_TIME, DATE, TIME_OF_DAY, LDATE

These concrete data types are supported when the inputs of LIMIT call is connected. This is valid for all 3 inputs MN, IN and MX.
Observe: Neuron Power Engineer does not support some of the concrete data types (e.g. LTIME). Otherwise these data types would be contained due to ANY_ELEMENTARY.

Example for calls of this function
PROGRAM Test1
  VAR
    result1 : INT;
    result2 : STRING[10];
  END_VAR
  result1 := LIMIT(MN := 5, IN := 99, MX := 100);        (* allowed *)
  result2 := LIMIT(MN := "a", IN := "aa", MX := "aaa");  (* NOT allowed *)
END_PROGRAM

Example with/without 'returnValueMustBeAssigned'

Example 1 for interface

...
{ CustomImplementation , CustomNamespace := iec61131}
...
FUNCTION GET_NAMED_MEMORY : ANY
  { altName := ""; ... }
  { ImplementationProperties ( ...; functionHasCFile; returnValueMustBeAssigned;) }
  VAR_INPUT
  ...
END_FUNCTION

Compare the following copy of the system block that has been slightly modified:

Example 2 for interface
{ CustomImplementation}
NAMESPACE Copies
FUNCTION GET_NAMED_MEMORY_Copy : INT
  { ImplementationProperties ( functionHasCFile;) }
END_FUNCTION
END_NAMESPACE
Example for calls of these functions
PROGRAM Test1
  VAR
    Var1 : REF_TO INT;
  END_VAR
  
  GET_NAMED_MEMORY();              (* NOT allowed because of 'returnValueMustBeAssigned' in the vendor block interface *) 
  Var1 := GET_NAMED_MEMORY();      (* allowed *)
 
  GET_NAMED_MEMORY_Copy();         (* allowed *) 
  Var1 := GET_NAMED_MEMORY_Copy(); (* allowed *)
END_PROGRAM

Function references

The pragma { FunctionReferences } must be used in a vendor block when functions of a library are called in the C-code of the vendor block. This pragma is needed so that Neuron Power Engineer gets sufficient information on the called functions when building the application that is using the vendor block.
Compare:

  • You do not need to insert this pragma, when only function blocks are called in the C-code of the vendor block.

  • You do not need to insert this pragma for ST/FBD/LD POUs that are calling functions. This pragma is automatically inserted by Neuron Power Engineer when you are specifying these POUs with value INTERFACE or DEPLOY to be part of a library.

Complete the pragma { FunctionReferences } by the names of the called functions. Separate the function names by the character ",".

Example for function references
{ CustomImplementation }
FUNCTION_BLOCK TestVendorFB
  USING logicals.standard.util.schedule; 
  { ImplementationProperties (functionHasCFile; ) }
  { FunctionReferences TO_INT, TO_SINT, MUL_TIME, AND }
 
  (* The functions "TO_INT", "TO_SINT", "MUL_TIME" and "AND" are called in the C-code of the vendor block "TestVendorFB". *)
 
  (* variable declarations *)
END_FUNCTION_BLOCK

Definitions for variables

It is possible to add some special definitions for declared variables – in addition to the statements/definitions already described under "Supported ST-syntax".

Syntax
{CustomImplementation}
NAMESPACE com.oem1.lib1
  FUNCTION_BLOCK name | FUNCTION name : data-type
    USING Namespace_1; (* possible statement, if a namespace should be used *)
    { list of interface statements; }
    { ImplementationProperties (...) };
 
    VAR_IN_OUT 
     name_1 : data-type := initial-value { REQUIRES_NON_TEMP_VALUE };
     ...
    END_VAR
 
    VAR | VAR_INPUT | VAR_OUTPUT | VAR_IN_OUT | VAR_GLOBAL | VAR_EXTERNAL
     name_1, name_2, ..., name_n : data-type := initial-value {
        description := "string";
        comment := "string";
        customDataJson := 'Json-String';
        concreteType := data-type;
        };
     ...
    END_VAR
 
  END_FUNCTION_BLOCK | END_FUNCTION
END_NAMESPACE

Definition for variable

Purpose

{REQUIRES_NON_TEMP_VALUE}

defines that temporary values must not be connected to the appropriate in-out
See the following example.

{
  description := "string";
  comment := "string";
  customDataJson := 'Json-String';
  concreteType := data-type;
}

specifies the following pieces of additional data (= data elements) for the variable:

  • a description (also known as long name)

  • a comment

  • a JSON-string

  • a concrete data type for the instance of a different vendor function block that contains inputs of a →generic data type
    (warning) The statement concreteType is absolutely necessary to have the required type information for the vendor function block with the ANY inputs when the application is built.

See "Defining description, comment, JSON string or type for variables or data types" for details.

Example with '{REQUIRES_NON_TEMP_VALUE}'

Example for interface of vendor block
{CustomImplementation}
NAMESPACE com.oem1.lib1
FUNCTION myFUN_noTV
    VAR_IN_OUT
        IO1 : INT {REQUIRES_NON_TEMP_VALUE} ;
    END_VAR
END_FUNCTION
END_NAMESPACE
Example for call of vendor block (integrated in library)
PROGRAM Test1
  USING com.oem1.lib1;
    VAR_TEMP
      tempVar1 : INT;
    END_VAR
    myFUN_noTV(IO1:=tempVar1);
    (* not allowed because of '{REQUIRES_NON_TEMP_VALUE}' in the vendor block interface and
       because 'tempVar1' is a temporary variable. *)
END_PROGRAM

Additional statements not to be used

The following statements are only included for reference. (warning) Do not use these statements for your manually created interfaces.

Syntax
{ DoNotValidateThisFile ('') }
 
{CustomImplementation}
{ AccessLevel := Private|Public }
 
{suppressWarning modelRuleNamespace.modelRuleId('reason for suppression'), scope:=element|file}
FUNCTION_BLOCK name | FUNCTION name : data-type
  USING Namespace_1; (* possible statement, if a namespace should be used *)
   ...
END_FUNCTION_BLOCK | END_FUNCTION

 

Statement

Purpose

{ DoNotValidateThisFile ('') }

ignores the entire contents of the current ST-object 
(warning) Neuron Power Engineer recommends that you use this statement for auto-generated ST-objects only. If you insert this statement at the beginning of a manually created interface anyway, you will not get any messages for faulty statements.

See "Statement to ignore ST-objects" for details on this statement.

{ AccessLevel := Private|Public }

(warning) At present, this statement is not supported to be used within vendor blocks.
The statement { AccessLevel := ...} is automatically generated by Neuron Power Engineer, in particular for a POU within a library as the POU is specified within a library configuration.

{suppressWarning modelRuleNamespace.modelRuleId('reason for suppression'), scope:=element|file}

(warning) At present, this statement is not supported to be used within vendor blocks.

See "Statement to suppress warnings" for details on this statement.